﻿#pragma once

// set ->key
// map ->key/value

// 改造成适用于set和map的模板

enum COLOR
{
	RED,
	BLACK
};

// 节点结构创建
template<class T>
struct RBTreeNode
{
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	//pair<k, v> _kv;  
	T _data;
	COLOR _col;

	// 初始化
	RBTreeNode(const T& data)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		//, _kv(kv)
		,_data(data)
		, _col(RED)
	{}
};

// 迭代器
template<class T, class Ref, class Ptr>
class __TreeIterator
{
public:
	typedef RBTreeNode<T> Node;
	typedef __TreeIterator<T, Ref, Ptr> Self;
	Node* _node;

	__TreeIterator(Node* node)
		:_node(node)
	{}

	Ref operator*()
	{
		return _node->_data ;
	}
	Ptr operator->()
	{
		return &_node->_data;
	}

	Self& operator++()
	{
		// ++时，需要明白树的遍历方式，这里是中序——左子树 根 右子树，整体思路围绕这个顺序，进行++

		// 两种情况：一，右子树不为空；二，右子树为空

		// 一：右子树不为空
		if (_node->_right)
		{
			// 找右树最左节点
			Node* cur = _node->_right;
			while (cur && cur->_left)
			{
				cur = cur->_left;
			}
			_node = cur;
		}
		// 二：右子树为空
		else
		{
			// 也有两种情况
			// 一是当前节点是父亲的左孩子，那么当整颗子树结束，会按中序，走到父节点
			// 二是当前节点是父亲的右孩子，那么当整颗子树结束，意味着父节点也结束，会走祖父节点
			Node* cur = _node;
			Node* parent = cur->_parent;

			// 这里是先将cur指向parent，parent指向他的parent再看他还是不是父亲的右，是说明往上层的树也结束了，
			// 继续走，直到他不是父亲的右，即为父亲的左，这时将_node指向parent,再继续往上走，因为是左树就还有走根和右子树
			while (parent && cur == parent->_right)
			{
				cur = parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}
	
	bool operator!=(const Self& s)
	{
		return _node != s._node;
	}

	bool operator==(const Self& s)
	{
		return _node == s._node;
	}
};


//  用节点创建树

// 因为set和map区别在于第二个模板参数不一样，所以在构建时只需要将第二个参数做到适用两个，这里就只使用T
// T是什么，由实例化时决定，set传K过来，就是<k , k>， map传pair，就是<K, pair<k,T>>，才能确定data里面存什么

// 由于map的pair设计不满足我们大小比较，所以需要写仿函数来取T里面的first，主要是pair，set的key就是data
// set-> RBTree<K, K, SetKeyOfT> _t;
// map-> RBTree<K, pair<const K, T>, MapKeyOfT> _t;

template<class K, class T, class KeyOfT>  // 这个KeyOfT，用于比较大小
class RBTree
{
	// 重定义节点，方便使用
	typedef RBTreeNode<T> Node;
	
public:
	typedef __TreeIterator<T, T&, T* > iterator;
	typedef __TreeIterator<T, const T&, const T*> const_iterator;

	iterator begin()
	{
		// 先找最左节点
		Node* cur = _root;

		while (cur && cur->_left)
		{
			cur = cur->_left;
		}
		return iterator(cur);
	}

	iterator end()
	{
		return iterator(nullptr);
	}

	const_iterator begin() const
	{
		// 先找最左节点
		Node* cur = _root;

		while (cur && cur->_left)
		{
			cur = cur->_left;
		}
		return const_iterator(cur);
	}

	const_iterator end() const
	{
		return const_iterator(nullptr);
	}


	// 插入
	// 由于存在const与非const，不能用非const去构造const，可以用Node*来构造const与非const
	//pair<iterator, bool> Insert(const T& data)
	// 接收时，如果类型相同就是拷贝构造，不同就构造
	pair<Node*, bool> Insert(const T& data)
	{
		// 为空，直接插入，创建头
		if (_root == nullptr)
		{
			_root = new Node(data);
			_root->_col = BLACK;

			return make_pair(_root, true);
		}
		// 不为空，插入节点

		Node* parent = nullptr;
		Node* cur = _root;
		KeyOfT kot; // 创建仿函数对象kot，调用他的重载（），就可以得到两个不同实例化的data值，从而比较大小

		// 难处理的是怎样比较data大小，要适用两个
		while (cur)
		{
			if (kot(cur->_data) < kot(data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kot(cur->_data) > kot(data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return make_pair(cur, false);
			}
		}

		//当前cur就是最后要插入的节点位置 插入新节点 ，需要给他确定颜色
		// 新插入的节点给红色，这样代价最小
		cur = new Node(data);
		Node* newnode = cur;
		cur->_col = RED;

		// 给了红色，需要去判断父亲，祖父，叔父的颜色，是否满足5个条件，当不满足时，需要 变色 or 旋转+变色
		// 首先判断当前cur是parent的左还是右
		if (kot(parent->_data) < kot(data))
		{
			parent->_right = cur;
			cur->_parent = parent;
		}
		else
		{
			parent->_left = cur;
			cur->_parent = parent;
		}

		// 当父亲是黑色节点，那么插入红色节点对整体没有影响，不作处理，只有父亲是红色节点才处理
		while (parent && parent->_col == RED)
		{
			// 再创建祖父，叔父
			Node* grandfather = parent->_parent;

			// 情况一：当前父亲是祖父的左孩子
			if (parent == grandfather->_left)
			{
				// 父亲是左孩子，叔叔就为右孩子
				Node* uncle = grandfather->_right;

				//一，叔叔存在 且为红色
				if (uncle && uncle->_col == RED)
				{
					// 这时只需要将叔叔和父亲变成黑色，同时，虽然这时祖父是黑色，但是不能确定这时的祖父是整个树
					// 的根还是子树的根，是子树的根就需要继续向上处理
					uncle->_col = parent->_col = BLACK;
					grandfather->_col = RED;

					// 继续往上处理
					cur = grandfather;
					parent = cur->_parent;
				}

				// 剩余情况一定不存在向上处理，因为上面还有节点不符合5大条件
				else // 其余情况 ：叔叔不存在或存在且为黑色
				{
					if (cur == parent->_left)
					{
						// 这时整个树是左边高，需要右单旋+变色
						RotateR(grandfather);
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					else  // cur = parent->_right
					{
						// 当为右孩子时，呈现就是上面左边高，下面右边高，需要双旋
						RotateL(parent);
						RotateR(grandfather);

						grandfather->_col = RED;
						cur->_col = BLACK;
					}
					break;
				}
			}

			// 情况二：当前父亲是祖父的右孩子
			else  // parent == grandfather->_right
			{
				Node* uncle = grandfather->_left;
				// 一： 叔叔存在且为红色
				if (uncle && uncle->_col == RED)
				{
					// 只变色
					uncle->_col = parent->_col = BLACK;
					grandfather->_col = RED;

					// 继续往上处理
					cur = grandfather;
					parent = cur->_parent;
				}
				else  // 二： 叔叔不存在或存在且为黑色
				{
					// cur是父亲的右孩子——左单旋
					if (cur == parent->_right)
					{
						RotateL(grandfather);
						// 再变色
						grandfather->_col = RED;
						parent->_col = BLACK;
					}
					else  // cur == parent->_left
					{
						// 双旋+变色
						RotateR(parent);
						RotateL(grandfather);

						grandfather->_col = RED;
						cur->_col = BLACK;
					}
					break;
				}
			}
		}
		// 整个处理完之后将根节点置为黑色
		_root->_col = BLACK;

		return make_pair(newnode,true);
	}


	// 左单旋
	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;

		parent->_right = subRL;
		subR->_left = parent;

		Node* parentParent = parent->_parent;

		parent->_parent = subR;
		if (subRL)
			subRL->_parent = parent;

		if (_root == parent)
		{
			_root = subR;
			subR->_parent = nullptr;
		}
		else
		{
			if (parentParent->_left == parent)
			{
				parentParent->_left = subR;
			}
			else
			{
				parentParent->_right = subR;
			}

			subR->_parent = parentParent;
		}
	}

	// 右单旋
	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

		parent->_left = subLR;
		if (subLR)
			subLR->_parent = parent;

		Node* parentParent = parent->_parent;

		subL->_right = parent;
		parent->_parent = subL;

		if (_root == parent)
		{
			_root = subL;
			subL->_parent = nullptr;
		}
		else
		{
			if (parentParent->_left == parent)
			{
				parentParent->_left = subL;
			}
			else
			{
				parentParent->_right = subL;
			}

			subL->_parent = parentParent;
		}
	}

	// 中序遍历
	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}

	void _InOrder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}

		_InOrder(root->_left);
		cout << root->_kv.first << " ";
		_InOrder(root->_right);
	}

	// 检查每条路径黑色节点数量
	bool Check(Node* root, int blacknum, const int refVal)
	{
		// 每条路径结束标志，走到空即结束
		if (root == nullptr)
		{
			// cout << blacknum << endl;
			if (blacknum != refVal)
			{
				cout << "存在黑色节点数量不相等的路径" << endl;
				return false;
			}

			return true;
		}
		//其他情况：
		if (root->_col == RED && root->_parent->_col == RED)
		{
			cout << "出现连续的红色节点，该位置异常" << endl;
			return false;
		}

		if (root->_col == BLACK)
		{
			++blacknum;
		}

		// 递归求每条路径黑色节点数，传值传参，当递归结束返回上一层时，blacknum会回到原来的值，
		// 方便同父的另一个子树使用统计该路径blacknum值。
		return Check(root->_left, blacknum, refVal)
			&& Check(root->_right, blacknum, refVal);


	}

	// 判断该红黑树是否满足性质
	bool IsBalance()
	{
		// 红黑树的性质
		// 1. 每个结点不是红色就是黑色
		// 2. 根节点是黑色的 
		// 3. 如果一个节点是红色的，则它的两个孩子结点是黑色的 
		// 4. 对于每个结点，从该结点到其所有后代叶结点的简单路径上，均 包含相同数目的黑色结点 
		// 5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
		if (_root == nullptr)
			return true;
		if (_root->_col == RED)
			return false;

		// 参考值
		int refVal = 0;
		Node* cur = _root;
		// 用最左路径算出参考值
		while (cur)
		{
			if (cur->_col == BLACK)
			{
				++refVal;
			}
			cur = cur->_left;
		}
		int blacknum = 0;
		return Check(_root, blacknum, refVal);
	}

	// 求树高度
	int Height()
	{
		return _Height(_root);
	}

	int _Height(Node* root)
	{
		if (root == nullptr)
			return 0;

		int leftHeight = _Height(root->_left);
		int rightHeight = _Height(root->_right);

		return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
	}

	// 
	size_t Size()
	{
		return _Size(_root);
	}

	size_t _Size(Node* root)
	{
		if (root == NULL)
			return 0;

		return _Size(root->_left)
			+ _Size(root->_right) + 1;
	}

	// 查找
	Node* Find(const T& data)
	{
		Node* cur = _root;
		while (cur)
		{
			if (kot(cur->_data) < kot(data))
			{
				cur = cur->_right;
			}
			else if (kot(cur->_data) > kot(data))
			{
				cur = cur->_left;
			}
			else
			{
				return cur;
			}
		}

		return NULL;
	}

private:

	Node* _root = nullptr;
};


//enum Colour
//{
//	RED,
//	BLACK
//};
//
//template<class T>
//struct RBTreeNode
//{
//	RBTreeNode<T>* _left;
//	RBTreeNode<T>* _right;
//	RBTreeNode<T>* _parent;
//
//	T _data;
//
//	Colour _col;
//
//	RBTreeNode(const T& data)
//		:_left(nullptr)
//		, _right(nullptr)
//		, _parent(nullptr)
//		, _data(data)
//		, _col(RED)
//	{}
//};
//
//template<class T>
//struct __TreeIterator
//{
//	typedef RBTreeNode<T> Node;
//	typedef __TreeIterator<T> Self;
//	Node* _node;
//
//	__TreeIterator(Node* node)
//		:_node(node)
//	{}
//
//	T& operator*()
//	{
//		return _node->_data;
//	}
//
//	T* operator->()
//	{
//		return &_node->_data;
//	}
//
//	Self& operator--();
//
//	Self& operator++()
//	{
//		if (_node->_right)
//		{
//			// 下一个就是右子树的最左节点
//			Node* cur = _node->_right;
//			while (cur->_left)
//			{
//				cur = cur->_left;
//			}
//
//			_node = cur;
//		}
//		else
//		{
//			// 左子树 根 右子树
//			// 右为空，找孩子是父亲左的那个祖先
//			Node* cur = _node;
//			Node* parent = cur->_parent;
//			while (parent && cur == parent->_right)
//			{
//				cur = parent;
//				parent = parent->_parent;
//			}
//
//			_node = parent;
//		}
//
//		return *this;
//	}
//
//	bool operator!=(const Self& s)
//	{
//		return _node != s._node;
//	}
//
//	bool operator==(const Self& s)
//	{
//		return _node == s._node;
//	}
//};
//
//// set->RBTree<K, K, SetKeyOfT> _t;
//// map->RBTree<K, pair<K, T>, MapKeyOfT> _t;
//template<class K, class T, class KeyOfT>
//class RBTree
//{
//	typedef RBTreeNode<T> Node;
//public:
//	typedef __TreeIterator<T> iterator;
//
//	iterator begin()
//	{
//		Node* cur = _root;
//		while (cur && cur->_left)
//		{
//			cur = cur->_left;
//		}
//
//		return iterator(cur);
//	}
//
//	iterator end()
//	{
//		return iterator(nullptr);
//	}
//
//	pair<iterator, bool> Insert(const T& data)
//	{
//		if (_root == nullptr)
//		{
//			_root = new Node(data);
//			_root->_col = BLACK;
//			return make_pair(iterator(_root), true);
//		}
//
//		Node* parent = nullptr;
//		Node* cur = _root;
//		KeyOfT kot;
//
//		while (cur)
//		{
//			if (kot(cur->_data) < kot(data))
//			{
//				parent = cur;
//				cur = cur->_right;
//			}
//			else if (kot(cur->_data) > kot(data))
//			{
//				parent = cur;
//				cur = cur->_left;
//			}
//			else
//			{
//				return make_pair(iterator(cur), false);
//			}
//		}
//
//		// 新增节点给红色
//		cur = new Node(data);
//		Node* newnode = cur;
//		cur->_col = RED;
//		if (kot(parent->_data) < kot(data))
//		{
//			parent->_right = cur;
//			cur->_parent = parent;
//		}
//		else
//		{
//			parent->_left = cur;
//			cur->_parent = parent;
//		}
//
//		while (parent && parent->_col == RED)
//		{
//			Node* grandfather = parent->_parent;
//			if (parent == grandfather->_left)
//			{
//				//     g
//				//   p   u
//				// c
//				Node* uncle = grandfather->_right;
//				if (uncle && uncle->_col == RED)
//				{
//					// 变色
//					parent->_col = uncle->_col = BLACK;
//					grandfather->_col = RED;
//
//					// 继续往上更新处理
//					cur = grandfather;
//					parent = cur->_parent;
//				}
//				else
//				{
//					if (cur == parent->_left)
//					{
//						// 单旋
//						//     g
//						//   p
//						// c
//						RotateR(grandfather);
//						parent->_col = BLACK;
//						grandfather->_col = RED;
//					}
//					else
//					{
//						// 双旋
//						//     g
//						//   p
//						//     c
//						RotateL(parent);
//						RotateR(grandfather);
//						cur->_col = BLACK;
//						grandfather->_col = RED;
//					}
//
//					break;
//				}
//			}
//			else  // parent == grandfather->_right
//			{
//				//     g
//				//   u   p 
//				//          c
//				//
//				Node* uncle = grandfather->_left;
//				if (uncle && uncle->_col == RED)
//				{
//					// 变色
//					parent->_col = uncle->_col = BLACK;
//					grandfather->_col = RED;
//
//					// 继续往上处理
//					cur = grandfather;
//					parent = cur->_parent;
//				}
//				else
//				{
//					if (cur == parent->_right)
//					{
//						RotateL(grandfather);
//						parent->_col = BLACK;
//						grandfather->_col = RED;
//					}
//					else
//					{
//						//     g
//						//   u   p 
//						//     c
//						//
//						RotateR(parent);
//						RotateL(grandfather);
//						cur->_col = BLACK;
//						grandfather->_col = RED;
//					}
//
//					break;
//				}
//			}
//		}
//
//		_root->_col = BLACK;
//
//		return make_pair(iterator(newnode), true);
//	}
//
//	void RotateL(Node* parent)
//	{
//		Node* subR = parent->_right;
//		Node* subRL = subR->_left;
//
//		parent->_right = subRL;
//		subR->_left = parent;
//
//		Node* parentParent = parent->_parent;
//
//		parent->_parent = subR;
//		if (subRL)
//			subRL->_parent = parent;
//
//		if (_root == parent)
//		{
//			_root = subR;
//			subR->_parent = nullptr;
//		}
//		else
//		{
//			if (parentParent->_left == parent)
//			{
//				parentParent->_left = subR;
//			}
//			else
//			{
//				parentParent->_right = subR;
//			}
//
//			subR->_parent = parentParent;
//		}
//	}
//
//	void RotateR(Node* parent)
//	{
//		Node* subL = parent->_left;
//		Node* subLR = subL->_right;
//
//		parent->_left = subLR;
//		if (subLR)
//			subLR->_parent = parent;
//
//		Node* parentParent = parent->_parent;
//
//		subL->_right = parent;
//		parent->_parent = subL;
//
//		if (_root == parent)
//		{
//			_root = subL;
//			subL->_parent = nullptr;
//		}
//		else
//		{
//			if (parentParent->_left == parent)
//			{
//				parentParent->_left = subL;
//			}
//			else
//			{
//				parentParent->_right = subL;
//			}
//
//			subL->_parent = parentParent;
//		}
//	}
//
//	void InOrder()
//	{
//		_InOrder(_root);
//		cout << endl;
//	}
//
//	void _InOrder(Node* root)
//	{
//		if (root == nullptr)
//			return;
//
//		_InOrder(root->_left);
//		cout << root->_kv.first << " ";
//		_InOrder(root->_right);
//	}
//
//	// 根节点->当前节点这条路径的黑色节点的数量
//	bool Check(Node* root, int blacknum, const int refVal)
//	{
//		if (root == nullptr)
//		{
//			//cout << balcknum << endl;
//			if (blacknum != refVal)
//			{
//				cout << "存在黑色节点数量不相等的路径" << endl;
//				return false;
//			}
//
//			return true;
//		}
//
//		if (root->_col == RED && root->_parent->_col == RED)
//		{
//			cout << "有连续的红色节点" << endl;
//
//			return false;
//		}
//
//		if (root->_col == BLACK)
//		{
//			++blacknum;
//		}
//
//		return Check(root->_left, blacknum, refVal)
//			&& Check(root->_right, blacknum, refVal);
//	}
//
//	bool IsBalance()
//	{
//		if (_root == nullptr)
//			return true;
//
//		if (_root->_col == RED)
//			return false;
//
//		//参考值
//		int refVal = 0;
//		Node* cur = _root;
//		while (cur)
//		{
//			if (cur->_col == BLACK)
//			{
//				++refVal;
//			}
//
//			cur = cur->_left;
//		}
//
//		int blacknum = 0;
//		return Check(_root, blacknum, refVal);
//	}
//
//	int Height()
//	{
//		return _Height(_root);
//	}
//
//	int _Height(Node* root)
//	{
//		if (root == nullptr)
//			return 0;
//
//		int leftHeight = _Height(root->_left);
//		int rightHeight = _Height(root->_right);
//
//		return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
//	}
//
//	size_t Size()
//	{
//		return _Size(_root);
//	}
//
//	size_t _Size(Node* root)
//	{
//		if (root == NULL)
//			return 0;
//
//		return _Size(root->_left)
//			+ _Size(root->_right) + 1;
//	}
//
//	Node* Find(const K& key)
//	{
//		Node* cur = _root;
//		while (cur)
//		{
//			if (cur->_kv.first < key)
//			{
//				cur = cur->_right;
//			}
//			else if (cur->_kv.first > key)
//			{
//				cur = cur->_left;
//			}
//			else
//			{
//				return cur;
//			}
//		}
//
//		return NULL;
//	}
//
//private:
//	Node* _root = nullptr;
//};
